package org.jeecg.modules.wlhy.utils;

import org.apache.commons.lang.StringUtils;
import org.jeecg.common.exception.JeecgBootException;
import org.jeecg.modules.wlhy.customer.entity.HyCustomerCompany;
import org.jeecg.modules.wlhy.customer.entity.HyCustomerConfig;
import org.jeecg.modules.wlhy.shipping.entity.HyShippingNote;

import java.math.BigDecimal;

public class HyWmCalcFeeUtil {
    //是否涨吨
    private static boolean getIsZd(HyShippingNote hyShippingNote, HyCustomerConfig customerConfig) {
        // 实际装载量    goodsWeightLoading
        BigDecimal goodsWeightLoading = hyShippingNote.getGoodsWeightLoading();
        // 实际卸货量  goodsWeightUnloading
        BigDecimal goodsWeightUnloading = hyShippingNote.getGoodsWeightUnloading();

        String izZd = getizZd(hyShippingNote,customerConfig);

        //启用涨吨计算时
        //涨吨运费计算规则: 运费=(原发-涨吨基数)*运费单价; 扣款=超出吨位*亏吨价格
        if ("1".equals(izZd)) {
            //卸货>装货
            if (goodsWeightUnloading.compareTo(goodsWeightLoading) == 1) {
                return true;
            }
        }
        return false;
    }

    //获取结算吨数
    private static BigDecimal getJss(HyShippingNote hyShippingNote, HyCustomerConfig customerConfig) {
        BigDecimal goodsWeightLoading = hyShippingNote.getGoodsWeightLoading();
        BigDecimal goodsWeightUnloading = hyShippingNote.getGoodsWeightUnloading();
        String payset = getPaySet(hyShippingNote, customerConfig);
        BigDecimal jss = goodsWeightUnloading; //结算吨数
        // payset 0两者取最小 1按发货量2按卸货量
        if ("0".equals(payset)) {
            //当卸货量>装货量时
            if (goodsWeightUnloading.compareTo(goodsWeightLoading) == 1) {
                jss = goodsWeightLoading;
            }
        } else if ("1".equals(payset)) {
            jss = goodsWeightLoading;
        } else if ("2".equals(payset)) {
            jss = goodsWeightUnloading;
        }
        return jss;
    }

    //获取亏吨数
    private static BigDecimal getGoodsWeightLoss(HyShippingNote hyShippingNote) {
        // 实际装载量    goodsWeightLoading
        BigDecimal goodsWeightLoading = hyShippingNote.getGoodsWeightLoading();
        // 实际卸货量  goodsWeightUnloading
        BigDecimal goodsWeightUnloading = hyShippingNote.getGoodsWeightUnloading();
        if (goodsWeightUnloading.compareTo(goodsWeightLoading) == 1) {
            return BigDecimal.ZERO; //不亏吨
        }
        BigDecimal goodsWeightLoss = BigDecimal.ZERO;
        //亏损方式 免赔方式(1吨数2比例)
        String lossType = hyShippingNote.getLossType();
        // 亏损免赔数  lossProportion
        BigDecimal lossProportion = hyShippingNote.getLossProportion();
        //亏吨计算 ,当卸货量>装货量时 ， 按装货量计算
        if ("1".equals(lossType)) {
            //亏吨  =  实际装载量 - 实际卸货量 - 亏损免赔比例
            goodsWeightLoss = goodsWeightLoading.subtract(goodsWeightUnloading).subtract(lossProportion).setScale(2, BigDecimal.ROUND_HALF_UP);
        } else if ("2".equals(lossType)) {
            //比例
            //亏吨  =  (实际装载量 - 实际卸货量) - (实际装载量*亏损免赔比例)
            goodsWeightLoss = goodsWeightLoading.subtract(goodsWeightUnloading).subtract(goodsWeightLoading.multiply(lossProportion)).setScale(2, BigDecimal.ROUND_HALF_UP);
        }
        //小于0时
        if (goodsWeightLoss.compareTo(BigDecimal.ZERO) < 0) {
            goodsWeightLoss = BigDecimal.ZERO;
        }
        return goodsWeightLoss;
    }

    private static BigDecimal getCostLoss(HyShippingNote hyShippingNote, HyCustomerConfig customerConfig, BigDecimal goodsWeightLoss) {
        if (goodsWeightLoss.compareTo(BigDecimal.ZERO) <= 0) {
            return BigDecimal.ZERO;
        }
        // 亏损货物单价  lossGoodsUnitPrice
        BigDecimal lossGoodsUnitPrice = hyShippingNote.getLossGoodsUnitPrice();
        //亏损金额
        BigDecimal costLoss = goodsWeightLoss.multiply(lossGoodsUnitPrice).setScale(2, BigDecimal.ROUND_HALF_UP);
        return costLoss;
    }

    private static BigDecimal getCostPay(HyShippingNote hyShippingNote, BigDecimal jss) {
        BigDecimal costPay = BigDecimal.ZERO;
        BigDecimal shippingUnitPrice = hyShippingNote.getShippingUnitPrice();
        //1单价4包车
        String shippingType = hyShippingNote.getShippingType();
        //运费计算方式(1单价4包车价)
        if ("1".equals(shippingType)) {
            //实际卸货量 * 单价
            costPay = jss.multiply(shippingUnitPrice);
        } else if ("4".equals(shippingType)) {
            //包车价
            costPay = shippingUnitPrice;
        }
        return costPay;
    }

    private static BigDecimal getAgentCostPay(HyShippingNote hyShippingNote, BigDecimal jss) {
        BigDecimal agentPrice = hyShippingNote.getAgentPrice();
        BigDecimal agentCostPay = BigDecimal.ZERO;
        //1单价4包车
        String shippingType = hyShippingNote.getShippingType();
        //运费计算方式(1单价4包车价)
        if ("1".equals(shippingType)) {
            //实际卸货量 * 单价
            agentCostPay = jss.multiply(agentPrice);
        } else if ("4".equals(shippingType)) {
            agentCostPay = agentPrice;
        }
        return agentCostPay;
    }

    private static BigDecimal getAgentCostPayShipping(HyShippingNote hyShippingNote , HyCustomerConfig customerConfig,BigDecimal agentCostPay) {

        BigDecimal agentCostPayShipping = agentCostPay;
        boolean isLoss = isLoss(hyShippingNote, customerConfig); //是否扣除亏吨
        if (isLoss) {//亏吨
            //差价模式货主是否扣除亏吨金额
            String izCjCustomerLoss = customerConfig.getIzCjCustomerLoss();
            if ("1".equals(izCjCustomerLoss)) {
                agentCostPayShipping = agentCostPayShipping.subtract(hyShippingNote.getCostLoss());
            }
        }
        return agentCostPayShipping;
    }
    private static BigDecimal getPayPlanCarrierFee(HyShippingNote hyShippingNote,BigDecimal costPayShipping) {
        String payType = hyShippingNote.getPayType();
        if (!"2".equals(payType)) {
            return BigDecimal.ZERO;
        }
        //车队长运费计算方式(0全部1按吨)
        String carrierFeeType = hyShippingNote.getCarrierFeeType();
        if ("0".equals(carrierFeeType)) {
            return costPayShipping;
        }
        //计算车队长运费
        if ("1".equals(carrierFeeType)) {
            BigDecimal carrierUnitFee = hyShippingNote.getCarrierUnitFee();
            BigDecimal goodsWeightLoading = hyShippingNote.getGoodsWeightLoading();
            BigDecimal carrierFee = carrierUnitFee.multiply(goodsWeightLoading);
            //司机运费，经过扣除 信息费、扣款、 油气 ， 如果不够支付车队长运费时， 车队长运费 = 司机运费
            if (carrierFee.compareTo(costPayShipping) > 0) {
                carrierFee = costPayShipping;
            }
            carrierFee = carrierFee.setScale(2, BigDecimal.ROUND_HALF_UP);
            return carrierFee;
        }
        //包车价
        if ("2".equals(carrierFeeType)) {
            BigDecimal carrierFee = hyShippingNote.getCarrierUnitFee();
            if (carrierFee.compareTo(costPayShipping) > 0) {
                carrierFee = costPayShipping;
            }
            return carrierFee;
        }
        return BigDecimal.ZERO;
    }
    private static BigDecimal getCarrierFee(HyShippingNote hyShippingNote, HyCustomerConfig customerConfig, BigDecimal costPayShipping, BigDecimal costLoss) {
        String payType = hyShippingNote.getPayType();
        if (!"2".equals(payType)) {
            return BigDecimal.ZERO;
        }
        //车队长运费计算方式(0全部1按吨2包车价)
        String carrierFeeType = hyShippingNote.getCarrierFeeType();
        if ("0".equals(carrierFeeType)) {
            return costPayShipping;
        }
        if ("2".equals(carrierFeeType)) {
            BigDecimal carrierFee = hyShippingNote.getCarrierUnitFee();
            if (carrierFee.compareTo(costPayShipping) > 0) {
                carrierFee = costPayShipping;
            }
            return carrierFee;
        }
        //计算车队长运费
        if ("1".equals(carrierFeeType)) {
            BigDecimal carrierUnitFee = hyShippingNote.getCarrierUnitFee();
            BigDecimal shippingUnitPrice = hyShippingNote.getShippingUnitPrice();
            if (carrierUnitFee.compareTo(shippingUnitPrice) > 0) {
                throw new JeecgBootException("车队长运费单价不能大于运费单价");
            }
            BigDecimal carrierFee = BigDecimal.ZERO;
            BigDecimal driverUnitFee = shippingUnitPrice.subtract(carrierUnitFee);
            BigDecimal goodsWeightLoading = hyShippingNote.getGoodsWeightLoading();
            BigDecimal goodsWeightUnloading = hyShippingNote.getGoodsWeightUnloading();
            String driverPayset = getdriverPayset(hyShippingNote , customerConfig);

            BigDecimal driverjss = goodsWeightUnloading; //结算吨数
            // driverPayset 0那个小用那个 1按发货量2按卸货量
            if ("0".equals(driverPayset)) {
                //当卸货量>装货量时
                if (goodsWeightUnloading.compareTo(goodsWeightLoading) == 1) {
                    driverjss = goodsWeightLoading;
                }
            } else if ("1".equals(driverPayset)) {
                driverjss = goodsWeightLoading;
            } else if ("2".equals(driverPayset)) {
                driverjss = goodsWeightUnloading;
            }
            BigDecimal driverFee = driverjss.multiply(driverUnitFee);
            if (driverFee.compareTo(BigDecimal.ZERO) == 0) {
                carrierFee = costPayShipping;
            }else {
                //亏吨
                driverFee = driverFee.subtract(costLoss);
                if (driverFee.compareTo(BigDecimal.ZERO) < 0) {
                    throw new JeecgBootException("运费核算错误");
                }
                String izDriverMl = getizDriverMl(hyShippingNote, customerConfig);
                if ("1".equals(izDriverMl)) {
                    String driverMlWs = getdriverMlWs(hyShippingNote, customerConfig);
                    if (StringUtils.isEmpty(driverMlWs)) {
                        driverMlWs = "10";
                    }
                    BigDecimal ml = new BigDecimal(driverMlWs);
                    driverFee = new BigDecimal(driverFee.divide(ml).intValue()).multiply(ml);
                }
                carrierFee = costPayShipping.subtract(driverFee);
            }
            return carrierFee;
        }
        return BigDecimal.ZERO;
    }

    private static BigDecimal getCostService(HyShippingNote hyShippingNote, HyCustomerCompany customerCompany, BigDecimal costPayShipping) {
        BigDecimal costService = BigDecimal.ZERO;
        BigDecimal companyCostServicePercent = customerCompany.getCostServicePercent();
        //服务费计算方式
        String costServiceType = customerCompany.getCostServiceType();
        if (!"1".equals(costServiceType) && !"2".equals(costServiceType)) {
            costServiceType = "1";
        }
        String payType = hyShippingNote.getPayType();
        //服务费计算
        BigDecimal tempCostPayShipping = costPayShipping;
        boolean preFeeDS = HyCfgUtil.isUsed2("preFeeDS");
        if ("3".equals(payType) && preFeeDS) {
            //预付运费计算方式  1按吨 2整车
            if("1".equals(hyShippingNote.getPreType())) {
                tempCostPayShipping = tempCostPayShipping.add(hyShippingNote.getPreFee());
            }
        }
        if ("2".equals(costServiceType)) {
            costService = tempCostPayShipping.multiply(companyCostServicePercent);
        } else if ("1".equals(costServiceType)) {
            BigDecimal companyCostServicePercent3 = BigDecimal.ONE.subtract(companyCostServicePercent);
            costService = tempCostPayShipping.divide(companyCostServicePercent3, 9, BigDecimal.ROUND_HALF_UP).subtract(tempCostPayShipping);
        } else {
            throw new JeecgBootException("服务费计算方式错误");
        }
        return costService;
    }

    private static String getPaySet(HyShippingNote hyShippingNote, HyCustomerConfig customerConfig) {
        String payType = hyShippingNote.getPayType();
        String payset = "0"; // 0那个小用那个 1按发货量2按卸货量
        if ("1".equals(payType) || "3".equals(payType)) {
            payset = getdriverPayset(hyShippingNote, customerConfig);
        } else if ("2".equals(payType)) {
            payset = customerConfig.getIzCarrierPayset();
        }
        return payset;
    }

    private static boolean isLoss(HyShippingNote hyShippingNote, HyCustomerConfig customerConfig) {
        String payType = hyShippingNote.getPayType();
        if ("1".equals(payType) || "3".equals(payType)) {
            return true;
        } else if ("2".equals(payType)) {
            String iz_carrier_loss = customerConfig.getIzCarrierLoss();
            if ("1".equals(iz_carrier_loss)) {
                return true;
            }
        }
        return false;
    }

    private static boolean isMl(HyShippingNote hyShippingNote, HyCustomerConfig customerConfig) {
        String payType = hyShippingNote.getPayType();
        if ("1".equals(payType) || "3".equals(payType)) {
            return "1".equals(getizDriverMl(hyShippingNote, customerConfig));
        } else if ("2".equals(payType)) {
            return "1".equals(customerConfig.getIzCarrierMl());
        }
        return false;
    }

    private static String getMlws(HyShippingNote hyShippingNote, HyCustomerConfig customerConfig) {
        String payType = hyShippingNote.getPayType();
        String mlws = "";
        if ("1".equals(payType) || "3".equals(payType)) {
            mlws = getdriverMlWs(hyShippingNote, customerConfig);
        } else if ("2".equals(payType)) {
            mlws = customerConfig.getCarrierMlWs();
        }
        if (StringUtils.isBlank(mlws)) {
            mlws = "10";
        }
        return mlws;
    }

    private static boolean isPreFee(HyShippingNote hyShippingNote) {
        return "3".equals(hyShippingNote.getPayType());
    }

    private static BigDecimal getPreFee(HyShippingNote hyShippingNote){
        if("3".equals(hyShippingNote.getPayType())){
            //预付运费计算方式  1按吨 2整车
            String preType = hyShippingNote.getPreType();
            BigDecimal preFee = null;
            if("2".equals(preType)) {
                preFee = hyShippingNote.getPreFee();
            }else if("1".equals(preType)){
                if(!HyCfgUtil.isUsed2("preFeeDS")){
                    preFee = hyShippingNote.getPreFee();
                }else {
                    return BigDecimal.ZERO;
                }
            }else{
                throw new JeecgBootException("预付运费计算方式错误");
            }
            if(preFee == null){
                throw new JeecgBootException("未预付完成");
            }
            return preFee;
        }
        return BigDecimal.ZERO;
    }
    //计算支付计划
    public static void calcPayPlan(HyShippingNote hyShippingNote,HyCustomerCompany customerCompany) {
        hyShippingNote.setCostServicePercent(customerCompany.getCostServicePercent());
        hyShippingNote.setMl(BigDecimal.ZERO);

        BigDecimal costPay = hyShippingNote.getCostPayShipping();
        if(BigDecimal.ZERO.compareTo(costPay) >0){
            throw new JeecgBootException("尾款核算错误");
        }

        BigDecimal costService = null;
        //服务费计算
        if ("3".equals(hyShippingNote.getOrderMode())) {
            costService = BigDecimal.ZERO;
        } else {
            costService = getCostService(hyShippingNote, customerCompany, hyShippingNote.getCostPay());
            costService = costService.setScale(2, BigDecimal.ROUND_HALF_UP);
        }


        //合计金额(货主交的运费)
        BigDecimal costPayTotal = costService.add(costPay);

        BigDecimal driverFee = hyShippingNote.getCostPay();
        driverFee = driverFee.setScale(2, BigDecimal.ROUND_HALF_UP);

        BigDecimal customerFee = costService.add(driverFee);
        customerFee = customerFee.setScale(2, BigDecimal.ROUND_HALF_UP);

        hyShippingNote.setGoodsWeightLoss(BigDecimal.ZERO);//亏吨
        hyShippingNote.setCostLoss(BigDecimal.ZERO);//亏损金额
        hyShippingNote.setCostService(costService);//服务费
        hyShippingNote.setCostPayTotal(costPayTotal); //合计金额
        hyShippingNote.setDriverFee(driverFee); //司机运费
        hyShippingNote.setCustomerFee(customerFee);//货主运费，开票金额

        //计算车队长运费
        BigDecimal carrierFee = BigDecimal.ZERO;
        if ("2".equals(hyShippingNote.getPayType())) {
            BigDecimal costPayShipping = hyShippingNote.getCostPayShipping();
            carrierFee = getPayPlanCarrierFee(hyShippingNote, costPayShipping);
        }
        hyShippingNote.setCarrierFee(carrierFee);//车队长运费

        if ("3".equals(hyShippingNote.getOrderMode())) {
            //计算差价模式经纪人运费
            // 经纪人应付运费
            BigDecimal jss = hyShippingNote.getGoodsWeightLoading();
            BigDecimal agentCostPay = getAgentCostPay(hyShippingNote, jss);
            agentCostPay = agentCostPay.setScale(2, BigDecimal.ROUND_HALF_UP);
            hyShippingNote.setAgentFee(agentCostPay);

            agentCostPay = agentCostPay.subtract(hyShippingNote.getCostPay1());//减去首付
            agentCostPay = agentCostPay.subtract(hyShippingNote.getCostPay2());//到付

            if(BigDecimal.ZERO.compareTo(agentCostPay) >= 0 ){
                throw new JeecgBootException("经纪人运费核算错误");
            }

            hyShippingNote.setCostService(BigDecimal.ZERO);//服务费
            hyShippingNote.setAgentCostPay(agentCostPay);
            hyShippingNote.setAgentCostPayShipping(agentCostPay);
            hyShippingNote.setAgentCostPayTotal(agentCostPay);
        }
    }


    public static void calcOrderMode1(HyShippingNote hyShippingNote, HyCustomerCompany customerCompany, HyCustomerConfig customerConfig , BigDecimal shippingSubFee) {

        String izUsedPayPlan = hyShippingNote.getIzUsedPayPlan();
        if("1".equals(izUsedPayPlan)) {
            calcPayPlan(hyShippingNote, customerCompany);
            return;
        }

        BigDecimal oldShippingUnitPrice = hyShippingNote.getShippingUnitPrice();
        String payType = hyShippingNote.getPayType();
        if("3".equals(payType)){
            //预付运费计算方式  1按吨 2整车
            //preFeeDS 预付运费按吨计算，车队代收运费时使用
            boolean preFeeDS = HyCfgUtil.isUsed2("preFeeDS");
            if("1".equals(hyShippingNote.getPreType()) && preFeeDS){
                BigDecimal newShippingUnitPrice = oldShippingUnitPrice.subtract(hyShippingNote.getPreUnitFee());
                if(newShippingUnitPrice.compareTo(BigDecimal.ZERO) < 0){
                    throw new JeecgBootException("运费单价计算错误");
                }
                hyShippingNote.setShippingUnitPrice(newShippingUnitPrice);
            }
        }
        //结算吨数
        BigDecimal jss = getJss(hyShippingNote, customerConfig);

        boolean iszd = getIsZd(hyShippingNote, customerConfig);
        BigDecimal costLoss = null;
        BigDecimal goodsWeightLoss = null;
        if(iszd){
            //涨吨
            // 实际装载量    goodsWeightLoading
            BigDecimal goodsWeightLoading = hyShippingNote.getGoodsWeightLoading();
            // 实际卸货量  goodsWeightUnloading
            BigDecimal goodsWeightUnloading = hyShippingNote.getGoodsWeightUnloading();
            goodsWeightLoss = goodsWeightUnloading.subtract(goodsWeightLoading).setScale(2, BigDecimal.ROUND_HALF_UP);

            // 亏损货物单价  lossGoodsUnitPrice
            BigDecimal lossGoodsUnitPrice = hyShippingNote.getLossGoodsUnitPrice();
            //金额
            costLoss = goodsWeightLoss.multiply(lossGoodsUnitPrice).setScale(2, BigDecimal.ROUND_HALF_UP);
        }else {
            //亏吨
            //亏吨数
            goodsWeightLoss = getGoodsWeightLoss(hyShippingNote);
            //亏损金额
            costLoss = getCostLoss(hyShippingNote, customerConfig, goodsWeightLoss);
        }

        //应付金额
        BigDecimal costPay = getCostPay(hyShippingNote, jss);
        costPay = costPay.setScale(2, BigDecimal.ROUND_HALF_UP);

        // 扣款
        if (hyShippingNote.getPenalty() != null) {
            costPay = costPay.subtract(hyShippingNote.getPenalty());
        }


        //实际运费金额
        BigDecimal costPayShipping = costPay;

        //补助，卸车补助 , 计入服务费核算中
//        if (hyShippingNote.getBz() != null) {
//            costPayShipping = costPayShipping.add(hyShippingNote.getBz());
//        }
//        if (hyShippingNote.getUnloadingBz() != null) {
//            costPayShipping = costPayShipping.add(hyShippingNote.getUnloadingBz());
//        }
//
        if(hyShippingNote.getServiceFee() != null){
            costPayShipping = costPayShipping.subtract(hyShippingNote.getServiceFee());
        }


        // 卸车费
        if (hyShippingNote.getUnloadingFee() != null) {
            costPayShipping = costPayShipping.subtract(hyShippingNote.getUnloadingFee());
        }
        // 扣款
//        if (hyShippingNote.getPenalty() != null) {
//            costPayShipping = costPayShipping.subtract(hyShippingNote.getPenalty());
//        }

        boolean isLoss = isLoss(hyShippingNote, customerConfig); //是否扣除亏吨
        if (isLoss) {
            //亏吨
            if (costLoss.compareTo(costPayShipping) >= 0) {
                throw new JeecgBootException("亏吨金额不能大于运费");
            }
            costPayShipping = costPayShipping.subtract(costLoss);
        }

        BigDecimal  ml = getMl(hyShippingNote, customerConfig , costPayShipping);
        hyShippingNote.setMl(ml);

        costPayShipping = costPayShipping.subtract(ml);
        costPayShipping = costPayShipping.setScale(2, BigDecimal.ROUND_HALF_UP);

        //服务费计算
        BigDecimal costService = null;
        if ("3".equals(hyShippingNote.getOrderMode())) {
            costService = BigDecimal.ZERO;
        }else {
            costService = getCostService(hyShippingNote, customerCompany, costPay);
            costService = costService.setScale(2, BigDecimal.ROUND_HALF_UP);
        }
        costService = costService.add(ml);
        if (isLoss) {
            costService = costService.add(costLoss);
        }
        if (hyShippingNote.getUnloadingFee() != null) {
            costService = costService.add(hyShippingNote.getUnloadingFee());
        }
        if (hyShippingNote.getServiceFee() != null) {
            costService = costService.add(hyShippingNote.getServiceFee());
        }
        //添加补助费给司机
        if (hyShippingNote.getBz()!= null) {
            costPayShipping = costPayShipping.add(hyShippingNote.getBz());
        }
        //合计金额(货主交的运费)
        BigDecimal costPayTotal = costService.add(costPayShipping).setScale(2, BigDecimal.ROUND_HALF_UP);
        BigDecimal customerFee = costPayTotal;
        BigDecimal driverFee = costPayShipping.setScale(2, BigDecimal.ROUND_HALF_UP);
        //扣除信息费
        if (hyShippingNote.getInformationFee() != null) {
            costPayShipping = costPayShipping.subtract(hyShippingNote.getInformationFee());
        }

        //扣除预付运费
        if(isPreFee(hyShippingNote)){
            //预付运费计算方式  1按吨 2整车
            //preFeeDS 预付运费按吨计算，车队代收运费时使用
            boolean preFeeDS = HyCfgUtil.isUsed2("preFeeDS");
            if("1".equals(hyShippingNote.getPreType()) && preFeeDS){
                BigDecimal preFee = hyShippingNote.getPreFee();
                costPay = costPay.add(preFee);
                driverFee = driverFee.add(preFee);
                customerFee = customerFee.add(preFee);
            }else {
                BigDecimal preFee = getPreFee(hyShippingNote);
                if (costPayShipping.compareTo(preFee) <= 0) {
                    throw new JeecgBootException("运费不能低于预付运费");
                }
                costPayShipping = costPayShipping.subtract(preFee);
            }
        }
        //扣除分段预付运费
        costPayShipping = costPayShipping.subtract(shippingSubFee);



        //油气结算,减去司机油气 , 需要计算完货主的合计金额， 再从司机运费里扣除
        if (!"0".equals(hyShippingNote.getIzUsedGas())) {
            BigDecimal gasRechargeAmount = hyShippingNote.getGasRechargeAmount();
            costPayShipping = costPayShipping.subtract(gasRechargeAmount);
        }

        if(costPayShipping.compareTo(BigDecimal.ZERO) < 0){
            throw new JeecgBootException("运费核算错误");
        }

        //计算车队长运费
        BigDecimal carrierFee = BigDecimal.ZERO;
        if ("2".equals(payType)) {
            carrierFee = getCarrierFee(hyShippingNote, customerConfig, costPayShipping, costLoss);
            carrierFee = carrierFee.setScale(2, BigDecimal.ROUND_HALF_UP);
            //司机运费，经过扣除 信息费、扣款、 油气 ， 如果不够支付车队长运费时， 车队长运费 = 司机运费
            if (carrierFee.compareTo(costPayShipping) > 0) {
                carrierFee = costPayShipping;
            }
        }

        hyShippingNote.setGoodsWeightLoss(goodsWeightLoss);//亏吨
        hyShippingNote.setCostLoss(costLoss);//亏损金额
        hyShippingNote.setCostPay(costPay);//应付金额
        hyShippingNote.setCostPayShipping(costPayShipping);// 实际运费金额
        hyShippingNote.setCostService(costService);//服务费
        hyShippingNote.setCostPayTotal(costPayTotal); //合计金额
        hyShippingNote.setCarrierFee(carrierFee);//车队长运费
        hyShippingNote.setDriverFee(driverFee); //司机运费
        hyShippingNote.setCustomerFee(customerFee);//货主运费，开票金额

        hyShippingNote.setShippingUnitPrice(oldShippingUnitPrice);//恢复单价
    }

    private static BigDecimal getMl(HyShippingNote hyShippingNote, HyCustomerConfig customerConfig, BigDecimal costPayShipping) {
        BigDecimal ml = BigDecimal.ZERO;
        boolean isMl = isMl(hyShippingNote, customerConfig);  //是否抹零
        if (isMl) {//抹零
            String mlwsStr = getMlws(hyShippingNote, customerConfig);//抹零位数
            BigDecimal mlws = new BigDecimal(mlwsStr);
            BigDecimal mlCostPayShipping = new BigDecimal(costPayShipping.divide(mlws).intValue()).multiply(mlws);
            ml = costPayShipping.subtract(mlCostPayShipping);
            if(StringUtils.isNotEmpty(hyShippingNote.getDriverMlFw())){
                String driverMlFw = hyShippingNote.getDriverMlFw();
                if("5".equals(driverMlFw) || "10".equals(driverMlFw)){
                    BigDecimal mlfw = new BigDecimal(driverMlFw);
                    if(ml.compareTo(mlfw) > 0){
                        ml = ml.subtract(mlfw);
                    }
                }else {
                    return BigDecimal.ZERO;
                }
            }
        }
        return ml;
    }

    //差价模式
    public static void calcOrderMode3(HyShippingNote hyShippingNote, HyCustomerCompany customerCompany, HyCustomerConfig customerConfig , BigDecimal shippingSubFee) {
        if(true){
            throw new JeecgBootException("暂不支持差价模式");
        }

        String izUsedPayPlan = hyShippingNote.getIzUsedPayPlan();
        if("1".equals(izUsedPayPlan)) {
            calcPayPlan(hyShippingNote, customerCompany);
            return;
        }

        BigDecimal oldAgentPrice = hyShippingNote.getAgentPrice();
        String payType = hyShippingNote.getPayType();
        if("3".equals(payType)){
            //预付运费计算方式  1按吨 2整车
            //preFeeDS 预付运费按吨计算，车队代收运费时使用
            boolean preFeeDS = HyCfgUtil.isUsed2("preFeeDS");
            if("1".equals(hyShippingNote.getPreType()) && preFeeDS){
                BigDecimal newAgentPrice = oldAgentPrice.subtract(hyShippingNote.getPreUnitFee());
                if(newAgentPrice.compareTo(BigDecimal.ZERO) < 0){
                    throw new JeecgBootException("货主运费单价计算错误");
                }
                hyShippingNote.setAgentPrice(newAgentPrice);
            }
        }

        calcOrderMode1(hyShippingNote, customerCompany, customerConfig, shippingSubFee);
        //结算吨数
        BigDecimal jss = getJss(hyShippingNote, customerConfig);
        // 经纪人应付运费
        BigDecimal agentCostPay = getAgentCostPay(hyShippingNote , jss);
        agentCostPay = agentCostPay.setScale(2, BigDecimal.ROUND_HALF_UP);

        // 经纪人实付运费
        BigDecimal agentCostPayShipping = getAgentCostPayShipping(hyShippingNote, customerConfig, agentCostPay);
        BigDecimal agentFee = agentCostPayShipping;
        agentFee = agentFee.setScale(2, BigDecimal.ROUND_HALF_UP);
        //扣除预付运费
        if(isPreFee(hyShippingNote)){
            BigDecimal preFee = getPreFee(hyShippingNote);
            if(agentCostPayShipping.compareTo(preFee) <= 0){
                throw new JeecgBootException("经纪人运费不能低于预付运费");
            }
            agentCostPayShipping = agentCostPayShipping.subtract(preFee);
        }
        //扣除分段预付运费
        agentCostPayShipping = agentCostPayShipping.subtract(shippingSubFee);

        agentCostPayShipping = agentCostPayShipping.setScale(2, BigDecimal.ROUND_HALF_UP);

        // 经纪人合计
        BigDecimal agentCostPayTotal = agentCostPayShipping;

        hyShippingNote.setCostService(BigDecimal.ZERO);//服务费
        hyShippingNote.setAgentCostPay(agentCostPay);
        hyShippingNote.setAgentCostPayShipping(agentCostPayShipping);
        hyShippingNote.setAgentCostPayTotal(agentCostPayTotal);
        hyShippingNote.setAgentFee(agentFee);

        hyShippingNote.setAgentPrice(oldAgentPrice);
    }


    public static String getdriverPayset(HyShippingNote hyShippingNote, HyCustomerConfig customerConfig){
        if(StringUtils.isEmpty(hyShippingNote.getIzDriverPayset())){
            hyShippingNote.setIzDriverPayset(customerConfig.getIzDriverPayset());
        }
        return hyShippingNote.getIzDriverPayset();
    }

    public static String getizDriverMl(HyShippingNote hyShippingNote, HyCustomerConfig customerConfig){
        if(StringUtils.isEmpty(hyShippingNote.getIzDriverMl())){
            hyShippingNote.setIzDriverMl(customerConfig.getIzDriverMl());
        }
        return hyShippingNote.getIzDriverMl();
    }

    public static String getdriverMlWs(HyShippingNote hyShippingNote, HyCustomerConfig customerConfig){
        if(StringUtils.isEmpty(hyShippingNote.getDriverMlWs())){
            hyShippingNote.setDriverMlWs(customerConfig.getDriverMlWs());
        }
        return hyShippingNote.getDriverMlWs();
    }

    public static String getizZd(HyShippingNote hyShippingNote, HyCustomerConfig customerConfig){
        if(StringUtils.isEmpty(hyShippingNote.getIzZd())){
            hyShippingNote.setIzZd(customerConfig.getIzZd());
        }
        return hyShippingNote.getIzZd();
    }

    public static BigDecimal getZdJs(HyShippingNote hyShippingNote, HyCustomerConfig customerConfig) {
        if (StringUtils.isEmpty(hyShippingNote.getZdJs())) {
            hyShippingNote.setZdJs(customerConfig.getZdJs().toPlainString());
        }
        return new BigDecimal(hyShippingNote.getZdJs());
    }
}

